#pragma once

#include <iostream>
#include <pthread.h>
#include <string>
#include <cstdlib>

using namespace std;


class Thread{
public:
    typedef enum{
        NEW = 0,
        RUNNING,
        EXITED
    }ThreadStatus;
    typedef void (*func_t)(void *);

    Thread(int num, func_t func,void *args):_tid(0), _status(NEW), _func(func),_args(args){
        char name[128];
        snprintf(name, sizeof(name), "thread-%d", num);
        _name = name;
    }


    int status(){
        return _status;
    }

    string threadname(){
        return _name;
    }

    pthread_t threadid(){
        if(_status == RUNNING){
            return _tid;
        }else{
            return 0;
        }
        
    }

    //pthread_create中传的函数只能有一个void*的参数，这里由于runHelper是类的成员函数多传了个*this
    //写成静态函数可以解决，但没有*this就不能直接访问类的属性了
    //在pthread_create的时候传入this
    static void *runHelper(void *args){
        //传入this，强转获得this
        Thread *ts = (Thread*)args;
        //_func(_args)
        
        //ts->_func(ts);
        (*ts)();

        return nullptr;
    }

    //仿函数
    void operator()(){
        if(_func != nullptr){
            _func(_args);
        }
        
    }

    //运行回调函数，设置状态为运行
    void run(){
        int n = pthread_create(&_tid, nullptr, runHelper, this);
        if(n != 0){
            exit(-1);
        }
        _status = RUNNING;
    }

    void join(){
        int n = pthread_join(_tid, nullptr);
        if(n != 0){
            cerr << "main thread join fail!   thread_name = " << _name << endl;
            exit(-1);
        }
        _status = EXITED;
    }

    ~Thread(){

    }

private:
    pthread_t _tid;
    string _name;

    //回调函数
    void *_args;
    func_t _func;

    ThreadStatus _status;

};